package asteroids.model.programs.expressions.ComposedExpressions;


import java.util.Arrays;

import asteroids.model.programs.expressions.ComposedExpression;
import asteroids.model.programs.expressions.Expression;
import asteroids.model.programs.statements.Statement;
import asteroids.model.programs.types.Type;
/**
 * Abstract class representing unary operations
 * 
 * @author Lennart De Graef
 *
 */
public abstract class UnaryExpression extends ComposedExpression {
	
	/**
	 * @param exp
	 * 		 	The given operand of the expression
	 * @post ...
	 * 		 | new.getOperand() = exp
	 */
	protected UnaryExpression(Expression exp, int line, int column){
		super(line, column);
		operand = exp;
	}
	
	/**
	 * Returns the operand of this expression.
	 * @return this.operand
	 */
	public Expression getOperand(){
		return operand;
	}
	
	private Expression operand;
	
	/**
	 * Return a textual representation of this unary expression 
	 * @return Always uses parentheses, to avoid problems when using sin(..)/...
	 *       | return(getOperatorSymbol() + "(" + getOperand().toString() + ")")
	 */
	@Override
	public String toString(){
		return getOperatorSymbol() + "(" + getOperand().toString() + ")";
	}
	
	public void setStatement(Statement newStatement){
		super.setStatement(newStatement);
		getOperand().setStatement(newStatement);
	}
	
	@Override
	public String typeCheckExpression(String errorMessage){
		Type operandType = getOperand().getType();
		String newErrorMessage = null;
		String correctOperandType = "";
		for(int i = 0; i < getOperandType().length -1; i++){
			correctOperandType += "a " + getOperandType()[i].toString() + " or ";
		}
		correctOperandType += "a " + getOperandType()[getOperandType().length - 1].toString() + " ";
		
		if(!Arrays.asList(getOperandType()).contains(operandType) && !Arrays.asList(getOperandType()).contains(Type.ANY)){
			newErrorMessage = ("Expression at line " + getOperand().getLine()
								+ " and column " + getOperand().getColumn()
								+ " is a " + operandType.toString() + " and should be a "
								+ correctOperandType + "\n");
		}
		
		String operandMessage = getOperand().typeCheckExpression(errorMessage);
		
		if(operandMessage != null && newErrorMessage == null) newErrorMessage = operandMessage;
		else if(operandMessage != null && newErrorMessage != null) newErrorMessage += operandMessage;
		
		return newErrorMessage;
		
	}
}
